using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace BlackAndWhiteBalance
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class FPS : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Core core;
        SpriteBatch spriteBatch;

        SpriteFont debugFont;

        KeyboardState currentKeyboardState;
        KeyboardState previousKeyboardState;

        // Show FPS by default in debug mode, but not in Release mode
        #if DEBUG
        bool isActive = true;
        #else
        bool isActive = false;
        #endif

        int frameRate;
        int frameCounter;
        TimeSpan elapsedTime;

        public FPS(Core core)
            : base(core)
        {
            this.core = core;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(core.GraphicsDevice);

            base.LoadContent();

            debugFont = core.Content.Load<SpriteFont>(@"Spritefonts\Debug");
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // Get the keyboard and mouse states:
            previousKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            if (currentKeyboardState.IsKeyDown(Keys.OemTilde) && currentKeyboardState.IsKeyDown(Keys.D0))
            {
                if (previousKeyboardState.IsKeyUp(Keys.OemTilde) || previousKeyboardState.IsKeyUp(Keys.D0))
                {
                    isActive = !isActive;
                    ResetCount();
                }
            }

            if (isActive)
            {
                // super cool, super sleek framerate algorithm taken from XNA Cretor's Club Sample: "Instanced Model"
                elapsedTime += gameTime.ElapsedGameTime;

                if (elapsedTime > TimeSpan.FromSeconds(1))
                {
                    elapsedTime -= TimeSpan.FromSeconds(1);
                    frameRate = frameCounter;
                    frameCounter = 0;
                } 
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            if (isActive)
            {
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                spriteBatch.DrawString(debugFont, "" + frameRate, new Vector2(10, 10), Color.Black);
                spriteBatch.End();
                frameCounter++;
            }

            base.Draw(gameTime);
        }

        void ResetCount()
        {
            //reset the fps count.
            elapsedTime = TimeSpan.Zero;
            frameCounter = 0;
        }
    }
}